package com.eci.context.context.feign;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;

import java.lang.reflect.Proxy;

/**
 * @author ：tangxuefeng
 * @date ：Created in 2019/4/16 14:29
 * @description：在spring创建bean的时候，检查feign的代理类实例bean，并再给他们代理为我们编写的代理类。
 * @version: : jdk1.8
 */

@Component
public class FeignBeanInitProxy implements BeanPostProcessor {

    @Value("${spring.application.name}")
    private String appName;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //判断bean是否是feign生成的实例
        Class<?> rClazz;
        try {
            rClazz = Class.forName(beanName);
        } catch (Exception e) {
            return bean;
        }
        if(rClazz == null){
            return bean;
        }
        if(rClazz.getAnnotation(FeignClient.class) != null){
            FeignInvocationHandler feignInvocationHandler = new FeignInvocationHandler(bean, appName);
            Object object = Proxy.newProxyInstance(feignInvocationHandler.getClass().getClassLoader(), bean
                    .getClass().getInterfaces(), feignInvocationHandler);
            //在bean创建后再使用动态代理放入包装的bean;
            return object;
        }
        return bean;
    }

}
